package com.jinzecloud.reportapproval.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.deepoove.poi.config.Configure;
import com.deepoove.poi.data.Pictures;
import com.deepoove.poi.plugin.table.LoopRowTableRenderPolicy;
import com.jinzecloud.reportapproval.bean.ConsCheckRecord;
import com.jinzecloud.reportapproval.bean.SoliChild;
import com.jinzecloud.reportapproval.bean.VegetationRecordForm;
import com.jinzecloud.reportapproval.dto.AdminDto;
import com.jinzecloud.reportapproval.dto.AuditParam;
import com.jinzecloud.reportapproval.dto.DataStagingParam;
import com.jinzecloud.reportapproval.enums.AuditRoleEnums;
import com.jinzecloud.reportapproval.enums.StateEnum;
import com.jinzecloud.reportapproval.enums.TableEnums;
import com.jinzecloud.reportapproval.mapper.SoliChildMapper;
import com.jinzecloud.reportapproval.service.SoliChildService;
import com.jinzecloud.reportapproval.utils.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;

import java.io.File;
import java.nio.file.StandardCopyOption;
import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.jinzecloud.reportapproval.mapper.SoilFirmnessMoistureMapper;
import com.jinzecloud.reportapproval.bean.SoilFirmnessMoisture;
import com.jinzecloud.reportapproval.service.SoilFirmnessMoistureService;

import javax.servlet.http.HttpServletRequest;


@Service("soilFirmnessMoistureService")
public class SoilFirmnessMoistureServiceImpl extends ServiceImpl<SoilFirmnessMoistureMapper, SoilFirmnessMoisture> implements SoilFirmnessMoistureService {

    @Autowired
    private SoliChildMapper soliChildMapper;

    @Autowired
    private HttpServletRequest request;

    @Autowired
    private SoliChildService soliChildService;

    @Autowired
    private FileUploadUtil fileUploadUtil;

    private SimpleDateFormat inputFormat = new SimpleDateFormat("yyyy-MM-dd"); // 原始格式


    private SimpleDateFormat sdf = new SimpleDateFormat("yyyy 年 MM 月 dd 日");

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<SoilFirmnessMoisture> page = this.page(
                new Query<SoilFirmnessMoisture>().getPage(params),
                new QueryWrapper<SoilFirmnessMoisture>().like("project_code",params.get("key")).orderByDesc("id")
        );

        return new PageUtils(page);
    }

    @Override
    public R saveSoilFirmnessMoisture(SoilFirmnessMoisture soilFirmnessMoisture) {
//        SoilFirmnessMoisture compute = null;
//        try {
//            compute = compute(soilFirmnessMoisture);
//        }catch (Exception e){
//            return R.error(400,"数据不完整");
//        }

        if(save(soilFirmnessMoisture)) {
            for (SoliChild soliChild : soilFirmnessMoisture.getSoliChilds()) {
                soliChild.setParentId(soilFirmnessMoisture.getId());
                soliChildMapper.insert(soliChild);
            }
        }
        return R.ok();
    }

    @Override
    public R updateSoilFirmnessMoisture(SoilFirmnessMoisture soilFirmnessMoisture) {
        List<SoliChild> parentId = soliChildMapper.selectList(new QueryWrapper<SoliChild>().eq("parent_id", soilFirmnessMoisture.getId()));
        if (soliChildMapper.deleteBatchIds(parentId) > 0) {
            if(updateById(soilFirmnessMoisture)) {
                for (SoliChild soliChild : soilFirmnessMoisture.getSoliChilds()) {
                    soliChild.setParentId(soilFirmnessMoisture.getId());
                    soliChildMapper.insert(soliChild);
                }
            }
        }
        return R.ok();
    }

    @Override
    public String viewPdf(Integer id) {
        SoilFirmnessMoisture moisture = getById(id);
        List<SoliChild> list = soliChildService.list(new QueryWrapper<SoliChild>().eq("parent_id", moisture.getId()));
        SoilFirmnessMoisture moistureUp = setSoilFirmnessMoisture(moisture, list);

        JSONObject data = JSONObject.parseObject(JSONObject.toJSONString(moistureUp));

        if (StrUtil.isNotEmpty(data.getString("detectPeople"))) data.put("detectPeople", Pictures.ofUrl(data.getString("detectPeople")).size(30, 10).create());
        if (StrUtil.isNotEmpty(data.getString("recorders"))) data.put("recorders", Pictures.ofUrl(data.getString("recorders")).size(30, 10).create());
        if (StrUtil.isNotEmpty(data.getString("checkers"))) data.put("checkers", Pictures.ofUrl(data.getString("checkers")).size(30, 10).create());


        //word
        File tempFile = WordUtil.getWordFile("template/moisture.docx", data, Configure.builder());

        if (tempFile == null) return null;
        String fileName = "土壤坚实度、土壤含水率测定记录表";
        String uploadDirectory = fileUploadUtil.getUploadFilePath("temp");
        String filePath = uploadDirectory + moisture.getProjectCode() + fileName;
        String savePath = RequestUtils.getBasePath(request) + "upload/temp/" + moisture.getProjectCode() +fileName;
        FileUtil.copyFile(tempFile, new File(filePath + ".docx"), StandardCopyOption.REPLACE_EXISTING);
        PDFUtil.WordToPdf(tempFile, new File(filePath + ".pdf"));

        update(new LambdaUpdateWrapper<SoilFirmnessMoisture>().set(SoilFirmnessMoisture::getWordPath, savePath + ".docx").set(SoilFirmnessMoisture::getPdfPath, savePath + ".pdf").eq(SoilFirmnessMoisture::getId, id));

        return RequestUtils.getBasePath(request) + "upload/temp/" + moisture.getProjectCode() + fileName + ".pdf";
    }

    @Override
    public Object auditList(DataStagingParam param) {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        LambdaQueryWrapper<SoilFirmnessMoisture> queryWrapper = new LambdaQueryWrapper<>();
        List<AdminDto> adminDto = AuditUtil.getAdminDto(authentication.getName());
        Set<Integer> roleSet = adminDto.stream().map(a -> StateEnum.getStateEnumByAuditRole(a.getRoleCode()).getState()).collect(Collectors.toSet());
        roleSet.remove(StateEnum.UN_SUBMIT.getState());
        queryWrapper.in(SoilFirmnessMoisture::getStatus, roleSet);
        return page(new Page<>(param.getPageNo(), param.getPageSize()), queryWrapper);
    }

    @Override
    public R audit(AuditParam auditParam) {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        List<AdminDto> adminDos = AuditUtil.getAdminDto(authentication.getName());
        if (CollectionUtil.isEmpty(adminDos)) return R.error("您没有审核权限！");
        SoilFirmnessMoisture soilFirmnessMoisture = this.getById(auditParam.getId());
        int state = soilFirmnessMoisture.getStatus();
        if (!auditParam.isState()) {
            updateById(soilFirmnessMoisture.setStatus(StateEnum.APPROVAL_NOT_PASS.getState())
                    .setAuditOpinion(auditParam.getAuditOpinion())
                    .setAuditDate(DateUtil.date().toDateStr()));
            return R.ok();
        }
        StateEnum currentAuditState = AuditUtil.getStateText(TableEnums.SOIL_FIRMNESS_MOISTURE.getTableName(), state);
        Integer nextAuditStateIndex = AuditUtil.getNextAuditState(TableEnums.SOIL_FIRMNESS_MOISTURE.getTableName(), state, adminDos.stream().map(AdminDto::getRoleCode).toList());
        AdminDto adminDto = adminDos.stream().filter(a -> StrUtil.equals(a.getRoleCode(), currentAuditState.getAuditRole()))
                .findFirst().orElse(null);
        if (adminDto == null || nextAuditStateIndex == null) return R.error("您没有审核权限！");
        if (StrUtil.equals(adminDto.getRoleCode(), AuditRoleEnums.CHECKER_PERSON.getCode())) soilFirmnessMoisture.setDetectPeople(adminDto.getAdSignature());
        if (StrUtil.equals(adminDto.getRoleCode(), AuditRoleEnums.RECORDER.getCode())) soilFirmnessMoisture.setRecorders(adminDto.getAdSignature());
        if (StrUtil.equals(adminDto.getRoleCode(), AuditRoleEnums.CHECKER.getCode())) soilFirmnessMoisture.setCheckers(adminDto.getAdSignature());
        soilFirmnessMoisture.setStatus(nextAuditStateIndex)
                .setAuditOpinion(auditParam.getAuditOpinion())
                .setAuditDate(DateUtil.date().toDateStr());
        updateById(soilFirmnessMoisture);
        return R.ok();
    }

    @Override
    public JSONObject soilFirmnessMoistureJson(String projectUuid) {
        SoilFirmnessMoisture moisture = getOne(new QueryWrapper<SoilFirmnessMoisture>().eq("project_code",projectUuid));
        if(moisture == null) return null;
        List<SoliChild> list = soliChildService.list(new QueryWrapper<SoliChild>().eq("parent_id", moisture.getId()));
        SoilFirmnessMoisture moistureUp = setSoilFirmnessMoisture(moisture, list);
        JSONObject data = JSONObject.parseObject(JSONObject.toJSONString(moistureUp));
        return data;
    }

    @Override
    public SoilFirmnessMoisture getProductNumber(String projectNumber) {
        return getOne(new QueryWrapper<SoilFirmnessMoisture>().eq("project_code", projectNumber));
    }


    /**
     * 计算
     * @param soilFirmnessMoisture
     * @return
     */
    public SoilFirmnessMoisture compute(SoilFirmnessMoisture soilFirmnessMoisture){
        List<SoliChild> soliChilds = soilFirmnessMoisture.getSoliChilds();

        System.out.println(soliChilds);

        //计算
        double totalWetWeight10 = 0;
        double totalWetWeight20 = 0;
        double totalSoilSolidity10 = 0;
        double totalSoilSolidity20 = 0;

        int count10 = 0;
        int count20 = 0;

        for (SoliChild soliChild : soliChilds) {
            if (soliChild.getType() == 1) {
                totalWetWeight10 += Double.parseDouble(soliChild.getSoilMoisture());
                totalSoilSolidity10 +=  Double.parseDouble(soliChild.getSoilSolidity());
                count10++;
            }
            if (soliChild.getType() == 2) {
                totalWetWeight20 += Double.parseDouble(soliChild.getSoilMoisture());
                totalSoilSolidity20 +=  Double.parseDouble(soliChild.getSoilSolidity());
                count20++;
            }
        }
        //含水层平均值0~10
        double waterLayerAverages10 = 0;
        //土壤结实层平均值0~10
        double soilLayerAverages10 = 0;
        //含水层平均值10~20
        double waterLayerAverages20 = 0;
        //土壤结实层平均值10~20
        double soilLayerAverages20 = 0;

        if(count10 > 0){
            //含水层平均值0~10
            waterLayerAverages10 = totalWetWeight10 / 3.0;
            soilFirmnessMoisture.setWaterLayerAverages10(String.format("%.1f",waterLayerAverages10));
            //土壤结实层平均值0~10
            soilLayerAverages10 = (totalSoilSolidity10) / 3.0;
            soilFirmnessMoisture.setSoilLayerAverages10(String.format("%.1f",soilLayerAverages10));

        }
        if(count20 > 0){
            //含水层平均值10~20
            waterLayerAverages20 = totalWetWeight20 / 3.0;
            soilFirmnessMoisture.setWaterLayerAverages20(String.format("%.1f",waterLayerAverages20));
            //土壤结实层平均值10~20
            soilLayerAverages20 = (totalSoilSolidity20) / 3.0;
            soilFirmnessMoisture.setSoilLayerAverages20(String.format("%.1f",soilLayerAverages20));
        }

        //含水总平均值
        double waterAvg = (waterLayerAverages10 + waterLayerAverages20)/2;
        soilFirmnessMoisture.setWaterAvg(String.format("%.1f",waterAvg));

        //结实总平均值
        double soilAvg = (soilLayerAverages10 + soilLayerAverages20)/2;
        soilFirmnessMoisture.setSoilAvg(String.format("%.1f",soilAvg));

        System.out.println(soilFirmnessMoisture);

        return soilFirmnessMoisture;
    }


    private SoilFirmnessMoisture setSoilFirmnessMoisture(SoilFirmnessMoisture soilFirmnessMoisture,List<SoliChild> soliChilds){
        for (SoliChild soliChild : soliChilds) {
            if (soliChild.getSamplingDepth().equals("0~10")) {
                if (soliChild.getPoints()==1) {
                    soilFirmnessMoisture.setWetWeight1_0_10(String.valueOf(soliChild.getWetWeight()));
                    soilFirmnessMoisture.setSoilMoisture1_0_10(String.valueOf(soliChild.getSoilMoisture()));
                    soilFirmnessMoisture.setDryWeight1_0_10(String.valueOf(soliChild.getDryWeight()));
                    soilFirmnessMoisture.setSoilSolidity1_0_10(String.valueOf(soliChild.getSoilSolidity()));
                } else if (soliChild.getPoints()==2) {
                    soilFirmnessMoisture.setWetWeight2_0_10(String.valueOf(soliChild.getWetWeight()));
                    soilFirmnessMoisture.setSoilMoisture2_0_10(String.valueOf(soliChild.getSoilMoisture()));
                    soilFirmnessMoisture.setDryWeight2_0_10(String.valueOf(soliChild.getDryWeight()));
                    soilFirmnessMoisture.setSoilSolidity2_0_10(String.valueOf(soliChild.getSoilSolidity()));
                } else if (soliChild.getPoints()==3) {
                    soilFirmnessMoisture.setWetWeight3_0_10(String.valueOf(soliChild.getWetWeight()));
                    soilFirmnessMoisture.setSoilMoisture3_0_10(String.valueOf(soliChild.getSoilMoisture()));
                    soilFirmnessMoisture.setDryWeight3_0_10(String.valueOf(soliChild.getDryWeight()));
                    soilFirmnessMoisture.setSoilSolidity3_0_10(String.valueOf(soliChild.getSoilSolidity()));
                }
            } else if (soliChild.getSamplingDepth().equals("10~20")) {
                if (soliChild.getPoints()==1) {
                    soilFirmnessMoisture.setWetWeight1_10_20(String.valueOf(soliChild.getWetWeight()));
                    soilFirmnessMoisture.setSoilMoisture1_10_20(String.valueOf(soliChild.getSoilMoisture()));
                    soilFirmnessMoisture.setDryWeight1_10_20(String.valueOf(soliChild.getDryWeight()));
                    soilFirmnessMoisture.setSoilSolidity1_10_20(String.valueOf(soliChild.getSoilSolidity()));
                } else if (soliChild.getPoints()==2) {
                    soilFirmnessMoisture.setWetWeight2_10_20(String.valueOf(soliChild.getWetWeight()));
                    soilFirmnessMoisture.setSoilMoisture2_10_20(String.valueOf(soliChild.getSoilMoisture()));
                    soilFirmnessMoisture.setDryWeight2_10_20(String.valueOf(soliChild.getDryWeight()));
                    soilFirmnessMoisture.setSoilSolidity2_10_20(String.valueOf(soliChild.getSoilSolidity()));
                } else if (soliChild.getPoints()==3) {
                    soilFirmnessMoisture.setWetWeight3_10_20(String.valueOf(soliChild.getWetWeight()));
                    soilFirmnessMoisture.setSoilMoisture3_10_20(String.valueOf(soliChild.getSoilMoisture()));
                    soilFirmnessMoisture.setDryWeight3_10_20(String.valueOf(soliChild.getDryWeight()));
                    soilFirmnessMoisture.setSoilSolidity3_10_20(String.valueOf(soliChild.getSoilSolidity()));
                }
            }
        }
        return soilFirmnessMoisture;
    }
}
